import sys
sys.setrecursionlimit(int(1e8))
n, m = map(int, input().split())
board = []
for _ in range(n):
    board.append(list(map(int, input().split())))

class UnionFind:
    def __init__(self,n):
        self.fa = list(range(n+1))
        self.size = [1] * (n+1)
    def find(self,x):
        if self.fa[x] != x:
            self.fa[x] = self.find(self.fa[x])
        return self.fa[x]
    def union(self,x,y):
        root_x = self.find(x)
        root_y = self.find(y)
        if root_x == root_y:
            return False
        if self.size[root_x] > self.size[root_y]:
            self.fa[root_y] = root_x
            self.size[root_x] += self.size[root_y]
        else:
            self.fa[root_x] = root_y
            self.size[root_y] += self.size[root_x]
        return True

uf = UnionFind(m*n)
max_height = [-1 for _ in range(m*n+1)]

def xy2idx(x,y):
    return x*n + y
for i in range(n):
    stack = []
    for j, num in enumerate(board[i]):
        while stack and num < board[i][stack[-1]]:
            top = stack.pop()
            uf.union(xy2idx(i,top),xy2idx(i,j))
        stack.append(j)

for j in range(m):
    stack = []
    for i in range(n):
        num = board[i][j]
        while stack and num < board[stack[-1]][j]:
            top = stack.pop()
            uf.union(xy2idx(i,j),xy2idx(top,j))
        stack.append(i)


for i in range(n):
    for j in range(m):
        max_height[xy2idx(i,j)] = max(max_height[xy2idx(i,j)], board[i][j])

ans = 0
for i in range(1, m*n+1):
    if uf.fa[i] == i:
        ans += uf.size[i] * max_height[i]
print(f"{ans/m*n:.6f}")
